package zetcode.games.snake;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

@SuppressWarnings("serial")
public class SnakePanel extends JPanel implements ActionListener{

	private final int WIDTH = 300;
	private final int HEIGHT = 300;
	private final int DOT_SIZE = 20;
	private final int ALL_DOTS = 225;
	private final int DELAY = 140;
	
	private int x[] = new int[ALL_DOTS];
	private int y[] = new int[ALL_DOTS];
	
	private int dots;
	private int apple_x;
	private int apple_y;
	
	private boolean left = false;
	private boolean right = true;
	private boolean up = false;
	private boolean down = false;
	
	private boolean inGame = true;
	private Timer timer;
	private Image dot;
	private Image head;
	private Image apple;
	
	private String dotPicFilepath = "/pics/dot.png";
	private String headPicFilepath = "/pics/head.png";
	private String applePicFilepath = "/pics/apple.png";
	
	public SnakePanel(){
		addKeyListener(new TAdapter());
		setBackground(Color.BLACK);
		
		ImageIcon iid = new ImageIcon(this.getClass().getResource(dotPicFilepath));
		dot = iid.getImage();
		
		ImageIcon iih = new ImageIcon(this.getClass().getResource(headPicFilepath));
		head = iih.getImage();
		
		ImageIcon iia = new ImageIcon(this.getClass().getResource(applePicFilepath));
		apple = iia.getImage();
		
		setFocusable(true);
		initGame();
	} 
	
	public void initGame(){
		dots = 3;
		
		for(int i = 0; i < dots; i++){
			x[i] = 60 - i*20;
			y[i] = 60;
		}
		
		locateApple();
		
		timer = new Timer(DELAY, this);
		timer.start();
	}
	
	public void paint(Graphics g){
		super.paint(g);
		
		if(inGame){
			g.drawImage(apple,  apple_x, apple_y, this);
			
			g.drawImage(head, x[0], y[0], this);
			for(int i = 1; i < dots; i++){
				g.drawImage(dot, x[i], y[i], this);
			}
			
			Toolkit.getDefaultToolkit().sync();
			g.dispose();
		}
		else{
			gameOver(g);
		}
	}
	
	public void gameOver(Graphics g){
		String msg = "Game Over";
		Font small = new Font("Times New Roman", Font.BOLD, 14);
		FontMetrics fm = this.getFontMetrics(small);
		
		g.setColor(Color.WHITE);
		g.setFont(small);
		g.drawString(msg, (WIDTH - fm.stringWidth(msg)) / 2, HEIGHT/ 2);
	}
	
	public void checkApple(){
		if(x[0] == apple_x && y[0] == apple_y){
			dots++;
			locateApple();
		}
	}
	
	public void move(){
		for(int i = dots; i > 0; i--){
			x[i] = x[i - 1];
			y[i] = y[i - 1];
		}
		
		if(left){x[0] -= DOT_SIZE;}
		if(right){x[0] += DOT_SIZE;}
		if(up){y[0] -= DOT_SIZE;}
		if(down){y[0] += DOT_SIZE;}
	}
	
	public void checkCollision(){
		for(int i = dots; i > 0; i--){
			if(i > 4 && x[0] == x[i] && y[0] == y[i]){inGame = false;}
		}
		
		if(y[0] > HEIGHT || y[0] < 0 || x[0] > WIDTH || x[0] < 0){inGame = false;}
	}
	
	public void locateApple(){
		int r = (int) (Math.random() * 15);
		apple_x = r * DOT_SIZE;
		r = (int) (Math.random() * 15);
		apple_y = r * DOT_SIZE;
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		if(inGame){
			checkApple();
			checkCollision();
			move();
		}
		
		repaint();
	}
	
	private class TAdapter extends KeyAdapter{
		public void keyPressed(KeyEvent e){
			int key = e.getKeyCode();
			
			if(key == KeyEvent.VK_LEFT && !right){
				left = true;
				up = false;
				down = false;
			}
			
			if(key == KeyEvent.VK_RIGHT && !left){
				right = true;
				up = false;
				down = false;
			}
			
			if(key == KeyEvent.VK_UP && !down){
				up = true;
				left = false;
				right = false;
			}
			
			if(key == KeyEvent.VK_DOWN && !up){
				down = true;
				left = false;
				right = false;
			}
		}
	}
}
